package netmorph.model.parts;

import javax.swing.table.DefaultTableModel;

import netmorph.model.NetmorphModel;

import neuron.NetworkStatistics;

public class BESOutputModel extends DefaultTableModel {

	static String[] params = new String[] { 
		"Basal # TS, mean", "Basal # TS, stdev", "Basal # TS, error", "Basal AsymT, mean", "Basal AsymT, stdev", "Basal AsymT, error", 
		"Oblique # TS, mean", "Oblique # TS, stdev", "Oblique # TS, error", "Oblique AsymT, mean", "Oblique AsymT, stdev", "Oblique AsymT, error", 
		"Apical # TS, mean", "Apical # TS, stdev", "Apical # TS, error", "Apical AsymT, mean", "Apical AsymT, stdev", "Apical AsymT, error", 
		};

	NetmorphModel model;
	String[] targets = new String[] { 
			"5.35", "4.41", "0.1", "0.14", "0.11", "0.01",
			"2.78", "2.65", "0.1", "0.08", "0.11", "0.01",
			"23.41", "12.55", "0.1", "0.24", "0.05", "0.01",
			};
	
	public double getTargetBTSMean() { return Double.parseDouble(targets[0]); }
	public double getTargetBTSDev() { return Double.parseDouble(targets[1]); }
	public double getTargetBTSError() { return Double.parseDouble(targets[2]); }
	
	public double getTargetBAsymMean() { return Double.parseDouble(targets[3]); }
	public double getTargetBAsymDev() { return Double.parseDouble(targets[4]); }
	public double getTargetBAsymError() { return Double.parseDouble(targets[5]); }

	public double getTargetOTSMean() { return Double.parseDouble(targets[6]); }
	public double getTargetOTSDev() { return Double.parseDouble(targets[7]); }
	public double getTargetOTSError() { return Double.parseDouble(targets[8]); }

	public double getTargetOAsymMean() { return Double.parseDouble(targets[9]); }
	public double getTargetOAsymDev() { return Double.parseDouble(targets[10]); }
	public double getTargetOAsymError() { return Double.parseDouble(targets[11]); }

	public double getTargetTTSMean() { return Double.parseDouble(targets[12]); }
	public double getTargetTTSDev() { return Double.parseDouble(targets[13]); }
	public double getTargetTTSError() { return Double.parseDouble(targets[14]); }
	
	public double getTargetTAsymMean() { return Double.parseDouble(targets[15]); }
	public double getTargetTAsymDev() { return Double.parseDouble(targets[16]); }
	public double getTargetTAsymError() { return Double.parseDouble(targets[17]); }

	
	public void dataChanged()
	{
		fireTableDataChanged();
	}
	
	public BESOutputModel(NetmorphModel model) {
		this.model = model;
	}
	
	@Override
	public int getColumnCount() {
		return 3;
	}
	 
	@Override
	public int getRowCount() {
		return params.length;
	}
	
	@Override
	public String getColumnName(int column) {
		return new String[] { "Output Variable", "Current", "Target" }[column];
	}
	
	@Override
	public boolean isCellEditable(int row, int column) {
		return column==2;
	}
	
	@Override
	public Object getValueAt(int row, int column) {
		String pname = params[row]; 
		if (column == 0) { return pname; } 
		else if (column == 1) {
			NetworkStatistics stats = model.getLastStats();
			if (stats == null) return "---"; 
			switch(row) {
				case 0: return stats.basalTermSegCountDist().mean();
				case 1: return stats.basalTermSegCountDist().stdev();
				case 2: return stats.basalTermSegCountDist().error(getTargetBTSMean(), getTargetBTSDev());
				case 3: return stats.basalAsymIndexDist().mean();
				case 4: return stats.basalAsymIndexDist().stdev();
				case 5: return "---";

				case 6: return stats.obliqueTermSegCountDist().mean();
				case 7: return stats.obliqueTermSegCountDist().stdev();
				case 8: return stats.obliqueTermSegCountDist().error(getTargetOTSMean(), getTargetOTSDev());
				case 9: return stats.obliqueAsymIndexDist().mean();
				case 10: return stats.obliqueAsymIndexDist().stdev();
				case 11: return "---";

				case 12: return stats.tuftTermSegCountDist().mean();
				case 13: return stats.tuftTermSegCountDist().stdev();
				case 14: return stats.tuftTermSegCountDist().error(getTargetTTSMean(), getTargetTTSDev());
				case 15: return stats.tuftAsymIndexDist().mean();
				case 16: return stats.tuftAsymIndexDist().stdev();
				case 17: return "---";

				default: return "---";
			}
		} 
		else { 
			return targets[row]; 
		}
	}
	
	@Override
	public void setValueAt(Object aValue, int row, int column) {
		if (column != 2) return;
		targets[row] = (String) aValue;
	}
	
}
